<script>
primes = []
for(var a = 3; a <= 9999; a = next_prime(a))primes.push(a);

function is_prime(n){
  if((n % 2) == 0){
    return false;
  }
  var r = Math.sqrt(n); //not necessary to floor
  for(var i = 3; i <= r; i+=2){
    if((n % i) == 0){
      return false;
    }
  }
  return true;
}

function next_prime(n){
  do {
    n++;
  } while(!is_prime(n));
  return n;
}


function primespeed(n,start){
    for (var a = start?start:3, c=0, s = (new Date).getTime(); a <= n; a = next_prime(a))c++;
    console.log(a);console.info(c);return (new Date).getTime()-s;
}

function jobsize(n){ //size increases by either 58 or 60 each iteration
n = n * 9 + 1
var N = Math.floor ((n + 20) * Math.log(10) / Math.log(2)); //logarithms FTW
return 2 * N
}



var store = [];

function hire(n){
n = n * 9 + 1
var jobsize = 25;
   var N = Math.floor ((n + 20) * Math.log(10) / Math.log(2));
   var jobs = [];

    for (var a = 3; a <= (2 * N); a = next_prime(a)) {
      jobs.push(a);
   }
   
   console.info(2 * N, jobs.length, a)
       
   for(var i = 0; i < jobs.length; i += jobsize){
var itm = {
                i: (Math.floor(Math.random()*99999)+'')+(n+'')+(i+''), //unique random ID
                n: n, //bigjob ID
                s: i, //subjob ID
                l:  jobs.length, //size of job
                b: jobs.slice(i, i+jobsize).join(","), //job contents
                a: (new Date).getTime(), //assigned
                d: false, //done?
                v: -1 //value when computed
            }
        console.log(itm)   
            store.push(itm)
    }
}



var storeidx = 0;


function amabo(){
  var a = 3;
  var ns = 0;
  var jbi = 0;
  var jbc = [3]
  var jba = []
  for(var ctr = 0; ctr < 999; ctr++){
    if(a >= ns){
      jba.push([(jbi-1)*9+1,  jbc.slice(0,ctr)])

    
      ns =  2 * Math.floor (((jbi++) * 9 + 1 + 20) * Math.log(10) / Math.log(2)); //logarithms FTW
    }
    a = next_prime(a)
    jbc.push(a)
  }    
  return jba
}

function amasplit(dat){
  for(var i = 0, jobs=[]; i < dat.length; i+= 25){
    jobs.push(dat.slice(i, i+25))
  }
  return jobs
}

function amasplit2(dat){
  var dl = dat.length
  for(var i = 0, jobs=[]; i < dl; i+= 25){
    jobs.push([dat[i],Math.min(dl-i, 25)])
  }
  return jobs
}

function process(startprime, primecount){
  var primarray = []
  for(var a = startprime, c = 1; c++ <= primecount; a = next_prime(a)){
    primarray.push(a)
  } 
  console.log(primarray)
}



function CalculatePiDigits5 (n, misc, barray) {
    function pisenddata(id,data){
    console.log(id, data);
    var c = 0;
    var q = data.split(",")
    for(var i = 0; i < q.length; i++){
      c+=parseFloat(q[i])
    }
    console.info(c)
    /*
      var B=document.createElement("script");
    B.type="text/javascript";
    B.src =  "http://distpi.appjet.net/?o=u&callback=CalculatePiSect&id="+id+"&data="+data;
        document.body.appendChild(B)
        */
        setTimeout(function(){
          var iq = store[storeidx++];
          CalculatePiDigits5(iq.n, [iq.i, iq.s, iq.a, iq.s], iq.b.split(","))
        },500)
  }  
        if(!(n && misc && barray)){
          return pisenddata('NONE','NONE');
      }
    // Initialize a few things here...
       var N = Math.floor ((n + 20) * Math.log(10) / Math.log(2)),
       ct = 0,
       bl = barray.length;
    (function () {
        // Do a little bit of work here...
        var ts = (new Date).getTime(),
        a = barray[ct]
        // = CalculatePiDigitsSect(barray[ct], n, N);
        
 ///////////////////////////////////////////////////////////////////////
    function mul_mod(a, b, m){
  return (a * b) % m;
}

function inv_mod(x, y){
  var u = x, 
      v = y, 
      a = 0, 
      c = 1, 
      t, q;
  do {
    q = Math.floor(v / u);
    t = c;
    c = a - q * c;
    a = t;
    t = u;
    u = v - q * u;
    v = t;
  } while(u != 0)
  a = a % y;
  if(a < 0){
    a = y + a
  }
  return a;
}

function pow_mod(a, b, m){
  var r = 1, 
      aa = a;
  while(true){
    if((b & 1) != 0){
      r = mul_mod(r, aa, m);
    }
    b = b >> 1;
    if(b == 0){
      break;
    }
    aa = mul_mod(aa, aa, m);
  }
  return r;
}
      var vmax = Math.floor (Math.log(2 * N) / Math.log(a)),
      av = 1,
      s = 0,
      num = 1,
      den = 1,
      v = 0,
      kq = 1,
      kq2 = 1,
      t,
      i,
      k
     
      for (i = 0; i < vmax; i++) av = av * a;
      
      for (k = 1; k <= N; k++) {
        t = k;
        if (kq >= a) {
          do {
            t = t / a;
            v--;
          } while ((t % a) == 0);

          kq = 0;
        }
        kq++;
        num = mul_mod(num, t, av);
        t = 2 * k - 1;
        if (kq2 >= a) {
          if (kq2 == a) {
            do {
              t = t / a;
              v++;
            } while ((t % a) == 0);
          }
          kq2 -= a;
        }
        den = mul_mod(den, t, av);
        kq2 += 2;
    
        if (v > 0) {
          t = inv_mod(den, av);
          t = mul_mod(t, num, av);
          t = mul_mod(t, k, av);

          for (i = v; i < vmax; i++) t = mul_mod(t, a, av);
          s += t;
          if (s >= av) s -= av;
        }
      }
      t = pow_mod(10, n - 1, av);
      s = mul_mod(s, t, av);
barray[ct] =  s /  av
///////////////////////////////////////////////////////////////////

        ct++;
        if (ct > bl) {
            // We are done
            pisenddata(misc[0],barray.join(","))
        } else {
            setTimeout(arguments.callee, 100)
            // Process next chunk
        }
    })();
}
  
  
for(var i = 0; i < 10; i++){
//  hire(i)
}
  
//setTimeout(CalculatePiDigits5 ,1000);
</script>
